package pers.sen.health.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.sen.health.date.DateUtils;
import pers.sen.health.general.EmptyUtil;
import pers.sen.health.mapper.OrderMapper;
import pers.sen.health.po.Member;
import pers.sen.health.po.Order;
import pers.sen.health.redis.RedisUtil;
import pers.sen.health.resources.RedisMessageConstant;
import pers.sen.health.service.MemberService;
import pers.sen.health.service.OrderService;
import pers.sen.health.service.OrderSettingService;

import java.util.Date;
import java.util.Map;

/**
 * @author Jason
 * @version 1.0.0
 * @date 2020/11/12 20:56
 * @Description TODO
 */
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    // 该服务模块即是生产者又是消费者，需要调用其他模块的功能
    @Reference
    private OrderSettingService orderSettingService;  // 不能使用Mapper，zookeeper上注册的是服务ServiceImpl模块

    @Reference
    private MemberService memberService;


    @Override
    @LcnTransaction
    public Order insertOrder(Map map) {
        // 1. 判断验证码是否有效
        String telephone = (String) map.get("telephone");
        String validateCode = (String) map.get("validateCode");

        String code = RedisUtil.get(RedisMessageConstant.SENDTYPE_ORDER + telephone);

        // 判断验证码是否过期，看能不能从Redis中获取
        if (EmptyUtil.isNullOrEmpty(code)) {
            throw new RuntimeException("验证码过期");
        }

        // 判断验证码是否准确
        if (!code.equals(validateCode)) {
            throw new RuntimeException("验证码错误");
        }

        // 2. 判断是否预约满：通过日期查询t_ordersetting表（满足日期，并且可预约人数大于已经预约人数）
        String orderdate = (String) map.get("orderDate");
        int count = orderSettingService.isOrderOk(orderdate);
        if (count <= 0) {
            // 没有查询到结果
            throw new RuntimeException("预约已满，请选择其他日期");
        }

        // 3. 判断是否重复预约（手机号查询会员表，会员存在：通过会员id、日期、套餐id查询订单表）
        Member member = memberService.findMemberByTelephone(telephone);  // mid telephone
        // 会员存在，不是第一次预约
        String sid = (String) map.get("setmealId");
        int mid;
        if (!EmptyUtil.isNullOrEmpty(member)) {
            mid = member.getId();
            // 通过会员id、日期、套餐id查询订单表
            int orderExist = baseMapper.findOrderBySIdAndOrderDateAndMId(Integer.parseInt(sid), orderdate, mid);
            if (orderExist > 0) {
                throw new RuntimeException("当日已经预约过，请更换日期");
            }

        } else {
            // 第一次预约更新会员表，获取会员id
            member = new Member();
            member.setName((String) map.get("name"));
            member.setSex((String) map.get("sex"));
            member.setIdCard((String) map.get("idCard"));
            member.setPhoneNumber(telephone);
            member.setRegTime(new Date());
            mid = memberService.saveMember(member);
        }


        //  4. 可以预约 多表更新 t_order t_ordersetting
        orderSettingService.updateReservationByOrderDate(orderdate);
        // 订单表的录入
        Order order = new Order();
        order.setMemberId(mid);
        order.setOrderDate(DateUtils.parseString2Date(orderdate, "yyyy-MM-dd"));
        order.setOrderType((String) map.get("orderType"));
        order.setSetmealId(Integer.parseInt(sid));
        order.setOrderStatus("未到诊");
        save(order);
        return order;

    }
}
